package com.ym.config;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class LockUtils {

    @Autowired
    private RedissonClient redissonClient;

    //加锁（这里是固定超时时间，时间单位为秒，防止死锁，如果不给固定时间默认触发看门狗机制）
    public boolean lock(String lockKey, Long leaseTime) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            log.info("尝试获取锁: {}", lockKey);
            leaseTime = Optional.ofNullable(leaseTime)
                    .filter(l -> l >= 0L)
                    .orElseGet(() -> -1L);
            boolean isLocked = lock.tryLock(-1, leaseTime, TimeUnit.SECONDS);
            if (isLocked) {
                log.info("成功获取锁: {}, 时间: {}", lockKey, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS")));
            } else {
                log.error("获取锁失败: {}", lockKey);
            }
            return isLocked;
        } catch (InterruptedException e) {
            log.error("获取锁过程中发生中断: {}", e.getMessage());
            Thread.currentThread().interrupt();
            return false;
        }
    }

    //解锁
    public void unlock(String lockKey) {
        RLock lock = redissonClient.getLock(lockKey);
        try {
            if (lock.isHeldByCurrentThread()) {
                log.info("成功释放锁: {}, 时间: {}", lockKey, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS")));
                lock.unlock();
            } else {
                log.warn("当前线程未持有锁: {}", lockKey);
            }
        } catch (Exception e) {
            log.error("释放锁失败: {}", e.getMessage());
        }
    }
}
